<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue监视数据更新的问题和原理</title>
  </title>
  <!-- 引入Vue -->
  <script src="../js/vue.js"></script>
</head>

<body>
  <!--
    Vue监视数据的原理：
      1. vue会监视data中所有层次的数据。
      2. 如何监测对象中的数据？
          通过setter实现监视，且要在new Vue时就传入要监测的数据。Vue 无法检测 property 的添加或移除
          (1).对象中后追加的属性，Vue默认不做响应式处理
          (2).如需给后添加的属性做响应式，请使用如下API：
                  Vue.set(target，propertyName/index，value) 或
                    vm.$set(target，propertyName/index，value)
      3. 如何监测数组中的数据？
            Vue 不能检测以下数组的变动：
                1.当你利用索引直接设置一个数组项时，例如：vm.items[indexOfItem] = newValue
                2.当你修改数组的长度时，例如：vm.items.length = newLength
            通过包裹数组更新元素的方法实现，本质就是做了两件事：
              (1).调用原生对应的方法对数组进行更新。
              (2).重新解析模板，进而更新页面。
      4.在Vue修改数组中的某个元素一定要用如下方法：
            1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
            2.Vue.set() 或 vm.$set()
      5.替换数组
         filter()、concat() 和 slice()。它们不会变更原始数组，而总是返回一个新数组。
         当使用非变更方法时，可以用新数组替换旧数组：
            example1.items = example1.items.filter(function (item) {
              return item.message.match(/Foo/)
            })
      特别注意：Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象(vm._data) 添加属性！！！
        注: 数据劫持可以理解成为vue对你写在data的数据会进行加工，让它们都变成响应式的
  		-->
  <!-- 准备容器 -->
  <div id="demo">

    <h2>人员列表</h2>
    <button @click="update">点击改变第一个人的信息</button>
    <ul>
      <li v-for="p in persons" :key="p.id">{{p.name}}--{{p.age}}</li>
    </ul>

  </div>


  <script type='text/javascript'>
    Vue.config.productionTip = false; //设置为 false 以阻止 vue 在启动时生成生产提示。

    // 创建一个Vue实例
    const vm = new Vue({
      el: '#demo',
      data: {
        name: 'Vue',
        age: 20,
        persons: [
          { id: '001', name: '张三', age: 18 },
          { id: '002', name: '李四', age: 24 },
          { id: '003', name: '王五', age: 30 },
        ],
      },
      methods: {
        update () {
          /* //有效的修改，Vue能够监控到,Vue加工的时候给对象里面的属性都加上了getter,setter
          this.persons[0].name = '马冬梅'
          this.persons[0].age = 30 */

          //无效的修改，Vue无法监控到,Vue加工的时候没有给数组添加getter,setter
          this.persons[0] = { id: '001', name: '马冬梅', age: 30 }

        }
      }


    })

  </script>

</body>

</html>